# This file is included in each target after defining it
# Contents here will finalize the steps of each target
# Some might be leaf nodes in the solution - which means they produce exe files
# Others might be internal nodes in the solution - which means they produce libraries required by other targets

if(NOT SET_UP_POST_TARGET_PROPERTIES_CONFIGURATION_DONE)
    set(SET_UP_POST_TARGET_PROPERTIES_CONFIGURATION_DONE TRUE)

    get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
    get_target_property(target_type ${PROJECT_NAME} TYPE)

    if(isMultiConfig)
        if(MSVC)
            if (target_type STREQUAL "EXECUTABLE")

                target_link_options(${PROJECT_NAME} PUBLIC
                    $<$<CONFIG:VkRelease>:/INCREMENTAL:NO>
                    $<$<CONFIG:DxRelease>:/INCREMENTAL:NO>
                    $<$<CONFIG:DxReleaseExperimental>:/INCREMENTAL:NO>
                    $<$<CONFIG:VkDebug>:/INCREMENTAL:YES>
                    $<$<CONFIG:DxDebug>:/INCREMENTAL:YES>
                    $<$<CONFIG:DxDebugExperimental>:/INCREMENTAL:YES>
                )

                # Dependencies for the target (both linking and include dir)
                target_link_libraries(${PROJECT_NAME} PRIVATE
                    MicroBench
                    )

                target_link_libraries(${PROJECT_NAME} PRIVATE
                    $<$<CONFIG:VkDebug>:${VULKAN_SDK_PATH}/Lib/vulkan-1.lib>
                    $<$<CONFIG:VkDebug>:${VULKAN_SDK_PATH}/Lib/shadercd.lib>
                    $<$<CONFIG:VkDebug>:${VULKAN_SDK_PATH}/Lib/shaderc_utild.lib>
                    $<$<CONFIG:VkDebug>:${VULKAN_SDK_PATH}/Lib/shaderc_combinedd.lib>
                    $<$<CONFIG:VkRelease>:${VULKAN_SDK_PATH}/Lib/vulkan-1.lib>
                    $<$<CONFIG:VkRelease>:${VULKAN_SDK_PATH}/Lib/shaderc.lib>
                    $<$<CONFIG:VkRelease>:${VULKAN_SDK_PATH}/Lib/shaderc_util.lib>
                    $<$<CONFIG:VkRelease>:${VULKAN_SDK_PATH}/Lib/shaderc_combined.lib>
                    )

                add_dependencies(${PROJECT_NAME} MicroBench DllFiles)

                set_target_properties(${PROJECT_NAME} PROPERTIES
                    VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:${PROJECT_NAME}>"
                    )
                # This is needed for windows to be able to run GUI apps and defines the main entry point
                #set_target_properties(${PROJECT_NAME} PROPERTIES
                #    WIN32_EXECUTABLE 1
                #    )

            endif()

            target_include_directories(
                ${PROJECT_NAME} PUBLIC 
                $<$<CONFIG:VkRelease>:${VULKAN_SDK_PATH}/Include>
                $<$<CONFIG:VkDebug>:${VULKAN_SDK_PATH}/Include>
                )

        elseif(APPLE)

            set (ENV_VARS "VK_ICD_FILENAMES=${MOLTEN_VK_ICD}" "VK_LAYER_PATH=${VK_LAYER_PATH}")
            set_target_properties(${PROJECT_NAME} PROPERTIES
                XCODE_GENERATE_SCHEME TRUE
                XCODE_SCHEME_WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
                XCODE_SCHEME_ENVIRONMENT "${ENV_VARS}"
                )

            target_include_directories(
                ${PROJECT_NAME} PUBLIC 
                $<$<CONFIG:VkRelease>: ${VULKAN_SDK_PATH}/include>
                $<$<CONFIG:VkDebug>: ${VULKAN_SDK_PATH}/include>
                )

            target_link_libraries(${PROJECT_NAME} PUBLIC 
                                    "-framework Appkit"
                                    "-framework Metalkit"
                                    "-framework Metal"
                                    "-framework Foundation"
                                    "-framework QuartzCore"
                                    "-framework IOKit"
                                    "-framework IOSurface"
                                    ${VULKAN_SDK_PATH}/lib/libvulkan.1.dylib
                                    ${VULKAN_SDK_PATH}/lib/libshaderc.a
                                    ${VULKAN_SDK_PATH}/lib/libshaderc_combined.a
                                    ${VULKAN_SDK_PATH}/lib/libshaderc_util.a) 

            if (target_type STREQUAL "EXECUTABLE")

                # Dependencies for the target (both linking and include dir)
                target_link_libraries(${PROJECT_NAME} PRIVATE
                    MicroBench
                    ${CMAKE_SOURCE_DIR}/Libs/GLFW/macos/lib-universal/libglfw3.a
                    )

                add_dependencies(${PROJECT_NAME} MicroBench)

                set_target_properties(${PROJECT_NAME} PROPERTIES
                    SUFFIX .m1exe
                    )

            else()

                add_dependencies(${PROJECT_NAME} MicroBench)
                set_target_properties(${PROJECT_NAME} PROPERTIES
                    SUFFIX .a
                    )

            endif()

        endif()

    endif()

    if (NOT ${PROJECT_NAME} STREQUAL "PerfCounters")

        add_definitions(-DUNICODE -D_UNICODE)

    endif()

    set_target_properties(${PROJECT_NAME} PROPERTIES
        RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../Bin/${CMAKE_BUILD_TYPE}"
        )

    add_compile_definitions(
        $<$<CONFIG:DxDebug>:_DEBUG=1>
        $<$<CONFIG:DxRelease>:_RELEASE=1>
        $<$<CONFIG:VkDebug>:_DEBUG=1>
        $<$<CONFIG:VkRelease>:_RELEASE=1>
    )

    set_source_files_properties(${ShaderFiles} PROPERTIES HEADER_FILE_ONLY TRUE)
    set_source_files_properties(${Assets} PROPERTIES HEADER_FILE_ONLY TRUE)
    source_group( "Header Files" FILES ${HeaderFiles} )
    source_group( "Source Files" FILES ${SourceFiles} )
    source_group( "Shader Files" FILES ${ShaderFiles} )
    source_group( "Resource Files" FILES ${Assets} )

    function(copy_attached_files target_name file_type files)
        set(valid_file_types "Shaders" "Assets")
        list(FIND valid_file_types ${file_type} valid_type)
        if (valid_type LESS 0)
            message(STATUS "valid_type=${valid_type}")
            message(FATAL_ERROR "Invalid file type: ${file_type}")
        endif()

        foreach(relfilename IN LISTS files)
            file(RELATIVE_PATH relative_path ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})

            if (${file_type} STREQUAL "Shaders")
                string(LENGTH "Shaders/" prefix_len)
                string(SUBSTRING ${relfilename} ${prefix_len} -1 filename)
                set(src_filepath ${CMAKE_SOURCE_DIR}/${relative_path}/${relfilename})
                set(dst_filepath ${CMAKE_SOURCE_DIR}/../Bin/$<CONFIG>/Shaders/${relative_path}/${filename})
            else()
                set(src_filepath ${CMAKE_SOURCE_DIR}/${relative_path}/${relfilename})
                set(dst_filepath ${CMAKE_SOURCE_DIR}/../Bin/$<CONFIG>/Assets/${relative_path}/${relfilename})
            endif()

            add_custom_command(OUTPUT ${dst_filepath}
                COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_filepath} ${dst_filepath}
                DEPENDS ${src_filepath}
                )

            list(APPEND dependent_files ${dst_filepath})
        endforeach()
        
        add_custom_target(${target_name}-${file_type}
            DEPENDS ${dependent_files}
            )
            
        get_target_property(target_folder ${target_name} FOLDER)
        set_target_properties(${target_name}-${file_type} PROPERTIES FOLDER ${target_folder})

        add_dependencies(${target_name} ${target_name}-${file_type})

    endfunction() # copy_attached_files

    # NVAPI shader files
    function (handle_nvapi target_name)
        file(GLOB_RECURSE nvapiShaderHeaders ${CMAKE_SOURCE_DIR}/../Libs/NVAPI/shaders/*)
        foreach(nvapiShaderHeader IN LISTS nvapiShaderHeaders)
            get_filename_component(nvapiShaderHeaderFileName ${nvapiShaderHeader} NAME)
            set(dst_filepath ${CMAKE_SOURCE_DIR}/../Bin/$<CONFIG>/Shaders/NVAPI/${nvapiShaderHeaderFileName})
            add_custom_command(OUTPUT ${dst_filepath}
                COMMAND ${CMAKE_COMMAND} -E copy_if_different ${nvapiShaderHeader} ${dst_filepath}
                DEPENDS ${nvapiShaderHeader}
                )
            list(APPEND nvapi_shader_files ${dst_filepath})
        endforeach()

        add_custom_target(${target_name}-nvapi
            DEPENDS ${nvapi_shader_files}
            )
        get_target_property(target_folder ${target_name} FOLDER)
        set_target_properties(${target_name}-nvapi PROPERTIES FOLDER ${target_folder})
        add_dependencies(${target_name} ${target_name}-nvapi)
    endfunction()
    
    if (DEFINED ShaderFiles)
        copy_attached_files(${PROJECT_NAME} "Shaders" "${ShaderFiles}")
        handle_nvapi(${PROJECT_NAME})
    endif()
    
    if (DEFINED Assets)
        copy_attached_files(${PROJECT_NAME} "Assets" "${Assets}")
    endif()

endif()
